home *** CD-ROM | disk | FTP | other *** search
/ HyperLib 1997 Winter - Disc 1 / HYPERLIB-1997-Winter-CD1.ISO.7z / HYPERLIB-1997-Winter-CD1.ISO / オンラインウェア / PRG / ICProgKit 1.3.sit / ICProgKit1.3 / Examples / SpaceAliens / SpaceAliens.p next >
Text File  |  1996-07-30  |  10KB  |  319 lines

  1. program SpaceAliens;
  2.     (* Space Aliens Ate My Icons *)
  3.     (* A drag and drop utility to fix the type and *)
  4.     (* creator of any dropped on file based on its *)
  5.     (* extension and the database of extension mappings *)
  6.     (* provided by Internet Config. *)
  7.  
  8.     uses
  9.         (* Basic system units.  Most of these are *)
  10.         (* automatically included under Think, but *)
  11.         (* they need to be explicitlt stated with CodeWarrior *)
  12.         Resources, Fonts, Windows, QuickDraw, Menus, TextEdit, Dialogs, Memory, Types,
  13.         Errors, Files, Finder, TextUtils, OSUtils, Processes, GestaltEqu, Dialogs,
  14.         
  15.         (* standard system units needed to do AppleEvents *)
  16.         (* remember that Think Pascal automatically uses *)
  17.         (* most of the base operating system *)
  18.         EPPC, AppleEvents, Events,
  19.  
  20.         (* standard IC units *)
  21.         ICTypes, ICAPI, ICKeys;
  22.  
  23. (* ***** Standard Subroutines ***** *)
  24.  
  25.     function ICGetPrefStr (inst: ICInstance; key: Str255; var attr: ICAttr; var str: Str255): ICError;
  26.         var
  27.             err: ICError;
  28.             size: longint;
  29.     begin
  30.         size := 256;
  31.         err := ICGetPref(inst, key, attr, @str, size);
  32.         if err <> noErr then begin
  33.             str := '';
  34.         end; (* if *)
  35.         ICGetPrefStr := err;
  36.     end; (* ICGetPrefStr *)
  37.  
  38.     function GotRequiredParams (theAppleEvent: AppleEvent): ICError;
  39.         (* standard AppleEvent routine copied out of NIM:IAC *)
  40.         var
  41.             typeCode: DescType;
  42.             actualSize: Size;
  43.             err: ICError;
  44.     begin
  45.         err := AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard, typeCode, nil, 0, actualSize);
  46.         if err = errAEDescNotFound then begin
  47.             GotRequiredParams := noErr;
  48.         end
  49.         else if err = noErr then begin
  50.             GotRequiredParams := errAEEventNotHandled;
  51.         end
  52.         else begin
  53.             GotRequiredParams := err;
  54.         end; (* if *)
  55.     end; (* GotRequiredParams *)
  56.  
  57. (* ***** Global Declarations ***** *)
  58.  
  59.     const
  60.         my_creator = 'SA8I';
  61.                     (* the application signature *)
  62.     var
  63.         quit_now: boolean;
  64.                     (* set to true when you want main loop to quit *)
  65.         instance: ICInstance;
  66.                     (* global connection to IC *)
  67.         mappings: Handle;
  68.                     (* the mapping preference as returned by IC *)
  69.  
  70. (* ***** Do The Hard Stuff ***** *)
  71.  
  72.     function ProcessDocument (fss: FSSpec): ICError;
  73.         (* this is the core of the program *)
  74.         (* the fss parameter is a file whose extension *)
  75.         (* we'll look up in the IC database *)
  76.         (* mappings global variable is already set up *)
  77.         (* to contain that database *)
  78.         var
  79.             err: ICError;
  80.             count: longint;
  81.                         (* total number of entries in database *)
  82.             i: longint;
  83.                         (* indexes over the database entries *)
  84.             this: ICMapEntry;
  85.                         (* an unpacked element of the *)
  86.                         (* mappings database, used while stepping *)
  87.                         (* through database *)
  88.             entry: ICMapEntry;
  89.                         (* a mappings database element *)
  90.                         (* used to record the best match *)
  91.             longest_len: integer;
  92.                         (* longest extension we've found so far *)
  93.             posndx: longint;
  94.                         (* the index into the mappings database *)
  95.             info: FInfo;
  96.                         (* temporary for changing type and creator *)
  97.     begin
  98.         (* count the total number of entries *)
  99.         err := ICCountMapEntries(instance, mappings, count);
  100.         if err <> noErr then begin
  101.             count := 0;
  102.         end; (* if *)
  103.         (* loop through the entries *)
  104.         (* looking for the longest match *)
  105.         longest_len := 0;
  106.         posndx := 0;
  107.         for i := 1 to count do begin
  108.             (* ICMGetEntry gets the entry from mappings *)
  109.             (* that starts at posndx *)
  110.             (* and puts it into the entry record *)
  111.             if ICGetMapEntry(instance, mappings, posndx, this) = noErr then begin
  112.                 (* increment posndx so that we get the next *)
  113.                 (* entry the next time around the loop *)
  114.                 posndx := posndx + this.total_length;
  115.                 (* the entry matches if *)
  116.                 (* not_incoming flag bit is clear *)
  117.                 (* it's longer than the previous max *)
  118.                 (* it's longer than the file name *)
  119.                 (* it matches the last N chars of the filename *)
  120.                 if not btst(this.flags, ICmap_not_incoming_bit) & (length(this.extension) > longest_len) & (length(this.extension) < length(fss.name)) & (IUEqualString(copy(fss.name,  length(fss.name) - length(this.extension) +1, length(fss.name)), this.extension) = 0) then begin
  121.                     (* record the new longest entry *)
  122.                     entry := this;
  123.                     longest_len := length(this.extension);
  124.                 end; (* if *)
  125.             end; (* if *)
  126.         end; (* for *)
  127.  
  128.         (* if we found any matches then *)
  129.         (* set the file type and creator appropriately *)
  130.         if longest_len > 0 then begin
  131.             err := HGetFInfo(fss.vRefNum, fss.parID, fss.name, info);
  132.             if err = noErr then begin
  133.                 info.fdCreator := entry.file_creator;
  134.                 info.fdType := entry.file_type;
  135.                 err := HSetFInfo(fss.vRefNum, fss.parID, fss.name, info);
  136.             end; (* if *)
  137.         end
  138.         else begin
  139.             err := noErr;
  140.         end; (* if *)
  141.  
  142.         quit_now := true;
  143.         ProcessDocument := err;
  144.     end; (* ProcessDocument *)
  145.  
  146. (* ***** AppleEvent Handlers ***** *)
  147.  
  148.     function HandleOpenApplication (var theAppleEvent: AppleEvent; var reply: AppleEvent; refcon: longint): OSErr;
  149.         (* the 'oapp' event handler, displays the about box *)
  150.         (* should most probably only do this if we're in *)
  151.         (* the foreground but that's just too complicated *)
  152.         (* for this example *)
  153.         var
  154.             err: ICError;
  155.             email_address: Str255;
  156.             junk_attr: longint;
  157.             junk: integer;
  158.             junk_icerr: ICError;
  159.     begin
  160.         (* debugger; *)
  161.         err := GotRequiredParams(theAppleEvent);
  162.         if err = noErr then begin
  163.             junk_icerr := ICGetPrefStr(instance, kICEmail, junk_attr, email_address);
  164.             ParamText(email_address, '', '', '');
  165.             junk := Alert(128, nil);
  166.             quit_now := true;
  167.         end; (* if *)
  168.         HandleOpenApplication := err;
  169.     end; (* HandleOpenApplication *)
  170.  
  171.     function HandleOpenDocuments (var theAppleEvent: AppleEvent;var  reply: AppleEvent; refcon: longint): OSErr;
  172.         (* a fairly standard 'odoc' event handler *)
  173.         (* gets the document list, counts the items in it *)
  174.         (* gets the FSSpec for each document and calls *)
  175.         (* ProcessDocument on it *)
  176.         var
  177.             fss: FSSpec;
  178.             doc_list: AEDescList;
  179.             index, item_count: longint;
  180.             junk_size: Size;
  181.             junk_keyword: AEKeyword;
  182.             junk_type: descType;
  183.             err, junk: ICError;
  184.     begin
  185.         err := AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, doc_list);
  186.         if err = noErr then begin
  187.             err := GotRequiredParams(theAppleEvent);
  188.             if err = noErr then begin
  189.                 err := AECountItems(doc_list, item_count);
  190.             end
  191.             else begin
  192.                 item_count := 0;
  193.             end; (* if *)
  194.             for index := 1 to item_count do begin
  195.                 if err = noErr then begin
  196.                     err := AEGetNthPtr(doc_list, index, typeFSS, junk_keyword, junk_type, @fss, sizeof(fss), junk_size);
  197.                     if err = noErr then begin
  198.                         err := ProcessDocument(fss);
  199.                     end; (* if *)
  200.                 end; (* if *)
  201.             end; (* for *)
  202.             junk := AEDisposeDesc(doc_list);
  203.         end; (* if *)
  204.         HandleOpenDocuments := err;
  205.     end; (* HandleOpenDocuments *)
  206.  
  207.     function HandleQuit (var theAppleEvent: AppleEvent;var reply: AppleEvent; refcon: longint): OSErr;
  208.         (* a fairly standard 'quit' event handler *)
  209.         (* sets quit_now so that the main event loop quits *)
  210.         var
  211.             err: ICError;
  212.     begin
  213.         err := GotRequiredParams(theAppleEvent);
  214.         if err = noErr then begin
  215.             quit_now := true;
  216.         end; (* if *)
  217.         HandleQuit := err;
  218.     end; (* HandleQuit *)
  219.  
  220. {$IFC not GENERATINGPOWERPC}
  221.     function StackPtr: longInt;
  222.     inline
  223.         $2E8F;
  224. {$ENDC}
  225.  
  226.     var
  227.         junkbool: boolean;
  228.         event: EventRecord;
  229.         err: ICError;
  230.         junk: ICError;
  231.         response: longint;
  232.         attr: longint;
  233.         i : longint;
  234. begin
  235.     (* Lots of Initializing stuff. *)
  236.     InitGraf(@qd.thePort);
  237.     InitFonts;
  238.     InitWindows;
  239.     InitMenus;
  240.     TEInit;
  241.     InitDialogs(nil);
  242.     (* Only a concern if you are compiling for 68K.*)
  243. {$IFC not GENERATINGPOWERPC}
  244.     SetApplLimit(Ptr(StackPtr - 32768));
  245. {$ENDC}
  246.     MaxApplZone;
  247.     for i := 1 to 3 do begin
  248.         MoreMasters;
  249.     end;
  250.  
  251.     (* First check for System 7.  OK, so we're supposed *)
  252.     (* to test for functionality but this is example *)
  253.     (* code. *)
  254.     if (Gestalt(gestaltSystemVersion, response) <> noErr) | (response < $700) then begin
  255.         ExitToShell;
  256.     end; (* if *)
  257.  
  258.     (* Now install our AppleEvent handles. *)
  259.     err := AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, @HandleOpenApplication, 0, false);
  260.     if err = noErr then begin
  261.         err := AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, @HandleOpenDocuments, 0, false);
  262.     end; (* if *)
  263.     if err = noErr then begin
  264.         err := AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, @HandleQuit, 0, false);
  265.     end; (* if *)
  266.  
  267.     (* startup Internet Config *)
  268.     if err = noErr then begin
  269.         err := ICStart(instance, my_creator);
  270.         if err = noErr then begin
  271.             err := ICFindConfigFile(instance, 0, nil);
  272.         end; (* if *)
  273.  
  274.     (* fetch the mappings preference *)
  275.         if err = noErr then begin
  276.             err := ICGetPrefHandle(instance, kICMapping, attr, mappings);
  277.         end; (* if *)
  278.  
  279.     (* enter main loop *)
  280.         if err = noErr then begin
  281.             quit_now := false;
  282.             while not quit_now do begin
  283.                 junkbool := WaitNextEvent(everyEvent, event, maxlongint, nil);
  284.                 case event.what of
  285.                     keyDown: 
  286.                         quit_now := true;
  287.                     kHighLevelEvent: 
  288.                         junk := AEProcessAppleEvent(event);
  289.                     otherwise
  290.                         ;
  291.                 end; (* case *)
  292.             end; (* while *)
  293.         end; (* if *)
  294.  
  295.         (* shut down IC, only if we successfully started it *)
  296.         junk := ICStop(instance);
  297.     end; (* if *)
  298.  
  299.     (* beep if we get any errors*)
  300.     (* sophisticated error handling this is not *)
  301.     (* a good place to put a breakpoint this is *)
  302.     if err <> noErr then begin
  303.         SysBeep(10);
  304.     end; (* if *)
  305. end. (* SpaceAliens *)
  306.  
  307.  
  308. (* 
  309. Updated from v1.0.1:
  310.  
  311. Changed to work with CW.
  312.  
  313. + Added Initialization code.
  314. + Listed all System Units used by the program.
  315. + Updated the 'copy' procedure used in ProcessDocument to
  316. reflect the fact that CW returns 0 if the integer parameters
  317. are out of range, rather than trying for a best fit as in Think.
  318. + Removed the SIZE resource from SpaceAliens.rsrc: this is generated by CW.
  319. *)